/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.github.nisrulz.sensey;

import ohos.sensor.agent.CategoryBodyAgent;
import ohos.sensor.agent.CategoryEnvironmentAgent;
import ohos.sensor.agent.CategoryLightAgent;
import ohos.sensor.agent.CategoryMotionAgent;
import ohos.sensor.agent.CategoryOrientationAgent;
import ohos.sensor.agent.CategoryOtherAgent;
import ohos.sensor.bean.CategoryBody;
import ohos.sensor.bean.CategoryEnvironment;
import ohos.sensor.bean.CategoryLight;
import ohos.sensor.bean.CategoryMotion;
import ohos.sensor.bean.CategoryOrientation;
import ohos.sensor.bean.CategoryOther;
import ohos.sensor.bean.SensorBase;
import ohos.sensor.listener.ICategoryBodyDataCallback;
import ohos.sensor.listener.ICategoryEnvironmentDataCallback;
import ohos.sensor.listener.ICategoryLightDataCallback;
import ohos.sensor.listener.ICategoryMotionDataCallback;
import ohos.sensor.listener.ICategoryOrientationDataCallback;
import ohos.sensor.listener.ICategoryOtherDataCallback;
import ohos.sensor.listener.ISensorDataCallback;

/**
 * 传导器管理类
 *
 * @since 2021-04-12
 */
public class SensorManager {
    /**
     * 传感器类型-BODY
     */
    public static final int CATEGORY_BODY = 10;
    /**
     * 传感器类型-BODY
     */
    public static final int CATEGORY_ENVIRONMENT = 20;
    /**
     * 传感器类型-LIGHT
     */
    public static final int CATEGORY_LIGHT = 30;
    /**
     * 传感器类型-MOTION
     */
    public static final int CATEGORY_MOTION = 40;
    /**
     * 传感器类型-ORIENTATION
     */
    public static final int CATEGORY_ORIENTATION = 50;
    /**
     * 传感器类型-OTHER
     */
    public static final int CATEGORY_OTHER = 60;
    private CategoryOrientationAgent mCategoryOrientationAgent;
    private CategoryLightAgent mCategoryLightAgent;
    private CategoryMotionAgent mCategoryMotionAgent;
    private CategoryEnvironmentAgent mCategoryEnvironmentAgent;
    private CategoryBodyAgent mCategoryBodyAgent;
    private CategoryOtherAgent mCategoryOtherAgent;

    /**
     * getCategoryOrientationAgent
     *
     * @return CategoryOrientationAgent
     */
    public CategoryOrientationAgent getCategoryOrientationAgent() {
        if (mCategoryOrientationAgent == null) {
            mCategoryOrientationAgent = new CategoryOrientationAgent();
        }
        return mCategoryOrientationAgent;
    }

    /**
     * getCategoryLightAgent
     *
     * @return CategoryLightAgent
     */
    public CategoryLightAgent getCategoryLightAgent() {
        if (mCategoryLightAgent == null) {
            mCategoryLightAgent = new CategoryLightAgent();
        }
        return mCategoryLightAgent;
    }

    /**
     * getCategoryMotionAgent
     *
     * @return CategoryMotionAgent
     */
    public CategoryMotionAgent getCategoryMotionAgent() {
        if (mCategoryMotionAgent == null) {
            mCategoryMotionAgent = new CategoryMotionAgent();
        }
        return mCategoryMotionAgent;
    }

    /**
     * getCategoryEnvironmentAgent
     *
     * @return CategoryEnvironmentAgent
     */
    public CategoryEnvironmentAgent getCategoryEnvironmentAgent() {
        if (mCategoryEnvironmentAgent == null) {
            mCategoryEnvironmentAgent = new CategoryEnvironmentAgent();
        }
        return mCategoryEnvironmentAgent;
    }

    /**
     * getCategoryBodyAgent
     *
     * @return CategoryBodyAgent
     */
    public CategoryBodyAgent getCategoryBodyAgent() {
        if (mCategoryBodyAgent == null) {
            mCategoryBodyAgent = new CategoryBodyAgent();
        }
        return mCategoryBodyAgent;
    }

    /**
     * getCategoryOtherAgent
     *
     * @return CategoryOtherAgent
     */
    public CategoryOtherAgent getCategoryOtherAgent() {
        if (mCategoryOtherAgent == null) {
            mCategoryOtherAgent = new CategoryOtherAgent();
        }
        return mCategoryOtherAgent;
    }

    /**
     * 根据SensorType获取对应的Sensor
     *
     * @param type SensorType
     * @param <S> SensorBase
     * @return SensorBase
     */
    public <S extends SensorBase> S getDefaultSensor(int type) {
        S sensor = null;
        if (type < CATEGORY_BODY) {
            sensor = (S) getCategoryBodyAgent().getSingleSensor(type); // CategoryBody
        } else if (type < CATEGORY_ENVIRONMENT) {
            int sensorType = type - CATEGORY_BODY; // CategoryEnvironment
            sensor = (S) getCategoryEnvironmentAgent().getSingleSensor(sensorType);
        } else if (type < CATEGORY_LIGHT) {
            int sensorType = type - CATEGORY_ENVIRONMENT; // CategoryLight
            sensor = (S) getCategoryLightAgent().getSingleSensor(sensorType);
        } else if (type < CATEGORY_MOTION) {
            int sensorType = type - CATEGORY_LIGHT; // CategoryMotion
            sensor = (S) getCategoryMotionAgent().getSingleSensor(sensorType);
        } else if (type < CATEGORY_ORIENTATION) {
            int sensorType = type - CATEGORY_MOTION; // CategoryOrientation
            sensor = (S) getCategoryOrientationAgent().getSingleSensor(sensorType);
        } else if (type < CATEGORY_OTHER) {
            int sensorType = type - CATEGORY_ORIENTATION; // CategoryOther
            sensor = (S) getCategoryOtherAgent().getSingleSensor(sensorType);
        }
        return sensor;
    }

    /**
     * 根据SensorType注册对应SensorDataCallback
     *
     * @param callback
     * @param sensors
     * @param interval
     * @param <S>
     * @param <T>
     */
    public <S extends SensorBase,
        T extends ISensorDataCallback> void registerListener(T callback,
                                                             S sensors,
                                                             long interval) {
        if (callback == null || sensors == null) {
            return;
        }
        if (sensors instanceof CategoryBody && callback instanceof ICategoryBodyDataCallback) {
            getCategoryBodyAgent()
                .setSensorDataCallback((ICategoryBodyDataCallback) callback, (CategoryBody) sensors, interval);
        } else if (sensors instanceof CategoryEnvironment && callback instanceof ICategoryEnvironmentDataCallback) {
            getCategoryEnvironmentAgent()
                .setSensorDataCallback((ICategoryEnvironmentDataCallback) callback,
                    (CategoryEnvironment) sensors,
                    interval);
        } else if (sensors instanceof CategoryLight && callback instanceof ICategoryLightDataCallback) {
            getCategoryLightAgent()
                .setSensorDataCallback((ICategoryLightDataCallback) callback, (CategoryLight) sensors, interval);
        } else if (sensors instanceof CategoryMotion && callback instanceof ICategoryMotionDataCallback) {
            getCategoryMotionAgent()
                .setSensorDataCallback((ICategoryMotionDataCallback) callback, (CategoryMotion) sensors, interval);
        } else if (sensors instanceof CategoryOrientation && callback instanceof ICategoryOrientationDataCallback) {
            getCategoryOrientationAgent()
                .setSensorDataCallback((ICategoryOrientationDataCallback) callback,
                    (CategoryOrientation) sensors,
                    interval);
        } else if (sensors instanceof CategoryOther && callback instanceof ICategoryOtherDataCallback) {
            getCategoryOtherAgent()
                .setSensorDataCallback((ICategoryOtherDataCallback) callback, (CategoryOther) sensors, interval);
        }
    }

    /**
     * 根据SensorType移除对应SensorDataCallback
     *
     * @param callback
     * @param sensors
     * @param <S>
     * @param <T>
     */
    public <S extends SensorBase, T extends ISensorDataCallback> void unregisterListener(T callback, S sensors) {
        if (callback == null || sensors == null) {
            return;
        }
        if (sensors instanceof CategoryBody && callback instanceof ICategoryBodyDataCallback) {
            getCategoryBodyAgent()
                .releaseSensorDataCallback((ICategoryBodyDataCallback) callback, (CategoryBody) sensors);
        } else if (sensors instanceof CategoryEnvironment && callback instanceof ICategoryEnvironmentDataCallback) {
            getCategoryEnvironmentAgent()
                .releaseSensorDataCallback((ICategoryEnvironmentDataCallback) callback, (CategoryEnvironment) sensors);
        } else if (sensors instanceof CategoryLight && callback instanceof ICategoryLightDataCallback) {
            getCategoryLightAgent()
                .releaseSensorDataCallback((ICategoryLightDataCallback) callback, (CategoryLight) sensors);
        } else if (sensors instanceof CategoryMotion && callback instanceof ICategoryMotionDataCallback) {
            getCategoryMotionAgent()
                .releaseSensorDataCallback((ICategoryMotionDataCallback) callback, (CategoryMotion) sensors);
        } else if (sensors instanceof CategoryOrientation && callback instanceof ICategoryOrientationDataCallback) {
            getCategoryOrientationAgent()
                .releaseSensorDataCallback((ICategoryOrientationDataCallback) callback, (CategoryOrientation) sensors);
        } else if (sensors instanceof CategoryOther && callback instanceof ICategoryOtherDataCallback) {
            getCategoryOtherAgent()
                .releaseSensorDataCallback((ICategoryOtherDataCallback) callback, (CategoryOther) sensors);
        }
    }
}
